#include "../include/test_framework.h"
#include <stdarg.h>

// 全局测试框架实例
test_framework_t g_test_framework = {0};

// 命令处理表
static cmd_handler_entry_t cmd_handlers[] = {
    {CMD_PHOTO,  "AT+AIGLASSPHOTO",  "执行拍照测试",        handle_photo_command},
    {CMD_RECORD, "AT+AIGLASSRECORD", "执行录像测试",        handle_record_command},
    {CMD_RTSP,   "AT+AIGLASSRTSP",   "执行RTSP流测试",      handle_rtsp_command},
    {CMD_WIFI,   "AT+AIGLASSWIFI",   "执行WiFi连接测试",    handle_wifi_command},
    {CMD_OTA,    "AT+AIGLASSOTA",    "执行OTA升级测试",     handle_ota_command},
    {CMD_STATUS, "AT+STATUS",        "查看系统状态",        handle_status_command},
    {CMD_HELP,   "AT+HELP",          "显示帮助信息",        handle_help_command},
};

// 框架初始化
int test_framework_init(void) {
    printf("=== AI Glass Linux 测试框架初始化 ===\n");
    
    // 初始化互斥锁
    if (pthread_mutex_init(&g_test_framework.status_mutex, NULL) != 0) {
        perror("status_mutex init failed");
        return -1;
    }
    
    if (pthread_mutex_init(&g_test_framework.log_mutex, NULL) != 0) {
        perror("log_mutex init failed");
        return -1;
    }
    
    // 初始化命令队列
    if (cmd_queue_init(&g_test_framework.cmd_queue) != 0) {
        printf("命令队列初始化失败\n");
        return -1;
    }
    
    // 设置初始状态
    g_test_framework.parser_status = THREAD_IDLE;
    g_test_framework.processor_status = THREAD_IDLE;
    g_test_framework.monitor_status = THREAD_IDLE;
    g_test_framework.running = 0;
    g_test_framework.interactive_mode = 1;
    
    // 设置信号处理
    setup_signal_handlers();
    
    printf("测试框架初始化完成\n");
    return 0;
}

// 框架清理
void test_framework_cleanup(void) {
    printf("\n=== 清理测试框架 ===\n");
    
    // 停止框架
    test_framework_stop();
    
    // 清理命令队列
    cmd_queue_cleanup(&g_test_framework.cmd_queue);
    
    // 销毁互斥锁
    pthread_mutex_destroy(&g_test_framework.status_mutex);
    pthread_mutex_destroy(&g_test_framework.log_mutex);
    
    printf("测试框架清理完成\n");
}

// 启动框架
int test_framework_start(void) {
    printf("启动测试框架...\n");
    
    g_test_framework.running = 1;
    
    // 创建命令解析线程
    if (pthread_create(&g_test_framework.cmd_parser_thread, NULL, 
                      command_parser_thread, NULL) != 0) {
        perror("创建命令解析线程失败");
        return -1;
    }
    
    // 创建命令处理线程
    if (pthread_create(&g_test_framework.cmd_processor_thread, NULL, 
                      command_processor_thread, NULL) != 0) {
        perror("创建命令处理线程失败");
        return -1;
    }
    
    // 创建监控线程
    if (pthread_create(&g_test_framework.monitor_thread, NULL, 
                      monitor_thread, NULL) != 0) {
        perror("创建监控线程失败");
        return -1;
    }
    
    log_message("INFO", "所有线程已启动");
    
    // 打印欢迎信息
    printf("\n========================================\n");
    printf("  AI Glass Linux 测试框架已启动\n");
    printf("  输入 'AT+HELP' 查看可用命令\n");
    printf("  输入 'AT+EXIT' 或 Ctrl+C 退出\n");
    printf("========================================\n\n");
    
    return 0;
}

// 停止框架
void test_framework_stop(void) {
    if (!g_test_framework.running) {
        return;
    }
    
    printf("正在停止测试框架...\n");
    g_test_framework.running = 0;
    
    // 唤醒所有等待的线程
    pthread_cond_broadcast(&g_test_framework.cmd_queue.not_empty);
    pthread_cond_broadcast(&g_test_framework.cmd_queue.not_full);
    
    // 等待线程结束
    if (g_test_framework.cmd_parser_thread) {
        pthread_cancel(g_test_framework.cmd_parser_thread);
        pthread_join(g_test_framework.cmd_parser_thread, NULL);
    }
    
    if (g_test_framework.cmd_processor_thread) {
        pthread_join(g_test_framework.cmd_processor_thread, NULL);
    }
    
    if (g_test_framework.monitor_thread) {
        pthread_cancel(g_test_framework.monitor_thread);
        pthread_join(g_test_framework.monitor_thread, NULL);
    }
    
    log_message("INFO", "所有线程已停止");
}

// 命令队列初始化
int cmd_queue_init(cmd_queue_t *queue) {
    if (!queue) return -1;
    
    queue->head = 0;
    queue->tail = 0;
    queue->count = 0;
    
    if (pthread_mutex_init(&queue->mutex, NULL) != 0) {
        return -1;
    }
    
    if (pthread_cond_init(&queue->not_empty, NULL) != 0) {
        pthread_mutex_destroy(&queue->mutex);
        return -1;
    }
    
    if (pthread_cond_init(&queue->not_full, NULL) != 0) {
        pthread_mutex_destroy(&queue->mutex);
        pthread_cond_destroy(&queue->not_empty);
        return -1;
    }
    
    return 0;
}

// 命令队列清理
void cmd_queue_cleanup(cmd_queue_t *queue) {
    if (!queue) return;
    
    pthread_mutex_destroy(&queue->mutex);
    pthread_cond_destroy(&queue->not_empty);
    pthread_cond_destroy(&queue->not_full);
}

// 推送命令到队列
int cmd_queue_push(cmd_queue_t *queue, const test_command_t *cmd) {
    if (!queue || !cmd) return -1;
    
    pthread_mutex_lock(&queue->mutex);
    
    // 等待队列有空间
    while (queue->count >= CMD_QUEUE_SIZE && g_test_framework.running) {
        pthread_cond_wait(&queue->not_full, &queue->mutex);
    }
    
    if (!g_test_framework.running) {
        pthread_mutex_unlock(&queue->mutex);
        return -1;
    }
    
    // 添加命令到队列
    queue->commands[queue->tail] = *cmd;
    queue->tail = (queue->tail + 1) % CMD_QUEUE_SIZE;
    queue->count++;
    
    // 通知有新命令
    pthread_cond_signal(&queue->not_empty);
    pthread_mutex_unlock(&queue->mutex);
    
    return 0;
}

// 从队列弹出命令
int cmd_queue_pop(cmd_queue_t *queue, test_command_t *cmd) {
    if (!queue || !cmd) return -1;
    
    pthread_mutex_lock(&queue->mutex);
    
    // 等待队列非空
    while (queue->count == 0 && g_test_framework.running) {
        pthread_cond_wait(&queue->not_empty, &queue->mutex);
    }
    
    if (!g_test_framework.running) {
        pthread_mutex_unlock(&queue->mutex);
        return -1;
    }
    
    // 取出命令
    *cmd = queue->commands[queue->head];
    queue->head = (queue->head + 1) % CMD_QUEUE_SIZE;
    queue->count--;
    
    // 通知队列有空间
    pthread_cond_signal(&queue->not_full);
    pthread_mutex_unlock(&queue->mutex);
    
    return 0;
}

// 检查队列是否为空
int cmd_queue_is_empty(cmd_queue_t *queue) {
    if (!queue) return 1;
    
    pthread_mutex_lock(&queue->mutex);
    int empty = (queue->count == 0);
    pthread_mutex_unlock(&queue->mutex);
    
    return empty;
}

// 检查队列是否已满
int cmd_queue_is_full(cmd_queue_t *queue) {
    if (!queue) return 1;
    
    pthread_mutex_lock(&queue->mutex);
    int full = (queue->count >= CMD_QUEUE_SIZE);
    pthread_mutex_unlock(&queue->mutex);
    
    return full;
}

// 解析命令类型
cmd_type_t parse_command_type(const char *cmd_str) {
    if (!cmd_str) return CMD_UNKNOWN;
    
    size_t num_handlers = sizeof(cmd_handlers) / sizeof(cmd_handlers[0]);
    
    for (size_t i = 0; i < num_handlers; i++) {
        if (strncasecmp(cmd_str, cmd_handlers[i].cmd_string, 
                       strlen(cmd_handlers[i].cmd_string)) == 0) {
            return cmd_handlers[i].type;
        }
    }
    
    // 特殊处理EXIT命令
    if (strncasecmp(cmd_str, "AT+EXIT", 7) == 0 || 
        strncasecmp(cmd_str, "EXIT", 4) == 0) {
        return CMD_EXIT;
    }
    
    return CMD_UNKNOWN;
}

// 解析命令参数
int parse_command_parameters(const char *input, test_command_t *cmd) {
    if (!input || !cmd) return -1;
    
    // 清除命令结构体
    memset(cmd, 0, sizeof(test_command_t));
    
    // 复制输入字符串
    char input_copy[MAX_CMD_LEN];
    strncpy(input_copy, input, sizeof(input_copy) - 1);
    input_copy[sizeof(input_copy) - 1] = '\0';
    
    // 去除换行符
    char *newline = strchr(input_copy, '\n');
    if (newline) *newline = '\0';
    
    // 查找参数分隔符
    char *space = strchr(input_copy, ' ');
    if (space) {
        *space = '\0';
        strncpy(cmd->parameters, space + 1, sizeof(cmd->parameters) - 1);
    }
    
    // 解析命令类型
    cmd->type = parse_command_type(input_copy);
    strncpy(cmd->cmd_string, input_copy, sizeof(cmd->cmd_string) - 1);
    cmd->timestamp = time(NULL);
    
    return 0;
}

// 处理命令
test_result_t process_command(const test_command_t *cmd) {
    if (!cmd) return TEST_PARAM_ERROR;
    
    size_t num_handlers = sizeof(cmd_handlers) / sizeof(cmd_handlers[0]);
    
    for (size_t i = 0; i < num_handlers; i++) {
        if (cmd->type == cmd_handlers[i].type) {
            return cmd_handlers[i].handler(cmd);
        }
    }
    
    return TEST_NOT_SUPPORTED;
}

// 日志输出函数
void log_message(const char *level, const char *format, ...) {
    pthread_mutex_lock(&g_test_framework.log_mutex);
    
    // 获取当前时间
    time_t now = time(NULL);
    struct tm *tm_info = localtime(&now);
    
    // 打印时间戳和级别
    printf("[%04d-%02d-%02d %02d:%02d:%02d] [%s] ",
           tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
           tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, level);
    
    // 打印格式化消息
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    
    printf("\n");
    fflush(stdout);
    
    pthread_mutex_unlock(&g_test_framework.log_mutex);
}

// 获取结果字符串
const char* get_result_string(test_result_t result) {
    switch (result) {
        case TEST_SUCCESS: return "SUCCESS";
        case TEST_FAILURE: return "FAILURE";
        case TEST_TIMEOUT: return "TIMEOUT";
        case TEST_PARAM_ERROR: return "PARAM_ERROR";
        case TEST_BUSY: return "BUSY";
        case TEST_NOT_SUPPORTED: return "NOT_SUPPORTED";
        default: return "UNKNOWN";
    }
}

// 获取线程状态字符串
const char* get_thread_status_string(thread_status_t status) {
    switch (status) {
        case THREAD_IDLE: return "IDLE";
        case THREAD_RUNNING: return "RUNNING";
        case THREAD_BUSY: return "BUSY";
        case THREAD_ERROR: return "ERROR";
        case THREAD_STOPPED: return "STOPPED";
        default: return "UNKNOWN";
    }
}

// 检查标准输入是否有数据可读
int check_stdin_ready(void) {
    fd_set readfds;
    struct timeval timeout;
    
    FD_ZERO(&readfds);
    FD_SET(STDIN_FILENO, &readfds);
    
    timeout.tv_sec = 0;
    timeout.tv_usec = 100000; // 100ms超时
    
    return select(STDIN_FILENO + 1, &readfds, NULL, NULL, &timeout) > 0;
}